<?php

namespace App\Services;

use App\Models\Car;
use App\Models\DriverOthers;
use App\Models\DriverRecordLog;
use App\Models\Drivers;
use App\Models\DriverWallets;
use App\Models\OrderDistance;
use App\Models\Orders;
use App\Models\RefundOrder;
use App\Models\ServiceType;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

/**
 * Class DriversOrderService
 * @package App\Services
 * 司机订单管理
 */
class DriversOrderService extends BaseService
{
    protected $error;
    protected $redis;
    private $model;

    function __construct()
    {
        $this->redis = new RedisOperation; //实例化redis
    }

    /**
     * 订单列表
     */
    public function drivers_order_list(int $driver_id, $page = 1, $size = 10)
    {
        $list = Orders::query()
            ->leftJoin('service_type', 'service_type.id', 'orders.service_type_id')
            ->leftJoin('order_distance', 'order_distance.order_id', 'orders.id')
            ->select('orders.id', 'orders.end_time', 'orders.created_at', 'service_type.name', 'order_distance.reality_start', 'order_distance.reality_end', 'orders.status', 'order_distance.book_start', 'order_distance.book_end')
            ->where('driver_id', '=', $driver_id)
            ->where('driver_id', '!=', 0)
            ->orderByDesc('orders.id')
            ->forPage($page, $size)
            ->get();
        return $list;
    }

    /**
     * @param int $driver_id
     * @return array|null
     * 首页订单状态
     */
    public function order_info_status(int $driver_id)
    {
        $ss = new DriversPostage();
        $infos = null;
        $info = Orders::query()->with('order_distance')
            ->select(['id', 'status', 'end_time', 'arrive_time', 'service_type_id', 'type'])
            ->where([['driver_id', $driver_id]])
            ->whereIn('status', ['2', '3'])
            ->first();
        if ($info) {
            if ($info->type == '0') {
                $infos = $ss->DriversEstimatedCosts($info->id, $info->service_type_id);
            } else {
                $infos = $ss->EstimatedCost($info->id);
            }
            $infos['status'] = $info->status;
            $infos['reality_start'] = $info->order_distance->reality_start;
            $infos['times'] = $info->arrive_time ? $info->arrive_time : 0; //到达上车点时间戳 默认0
            $infos['end_time'] = strtotime($info->end_time) ? strtotime($info->end_time) : 0; //到达上车点时间戳 默认0

        }

        return $infos;
    }

    /**
     * 订单详情
     */
    public function drivers_order_details(int $id)
    {
        $info = Orders::query()
            ->select(['id', 'status', 'user_id', 'order_sn', 'end_time', 'km', 'minute', 'driver_money', 'receive_time', 'summary_time', 'toll_price', 'stop_price', 'waiting_time_price'])
            ->where('id', $id)->with(['user:id,phone,name,avatar', 'order_distance:id,order_id,book_start,book_end,driver_details'])
            ->first();
        $info['km'] = $info->km . 'km';//基础费用
        $info['minute'] = $info->minute . '分钟';//基础费用
        $info['expenses_price'] = number_format(round($info->driver_money - ($info->toll_price + $info->stop_price), 2), 2, '.', ''); //基础费用
        $info['surcharges'] = number_format(($info->toll_price + $info->stop_price), 2, '.', ''); //附加费用包括停车费过路费
        return $info;
    }

    /**
     * 司机取消订单
     */
    public function cancellation_of_order(int $order_id)
    {
        $refund_order = new PassengerPayService();
        try {
            DB::transaction(function () use ($order_id, $refund_order) {
                $orders = Orders::query()->where([
                    ['id', $order_id],
                    ['status', '2']
                ])
                    ->lockForUpdate()
                    ->first();
                if ($orders) {
                    $orders->status = '-2'; //司机取消状态
                    $orders->cancel_time = time(); //取消时间
                    $orders->save();
                }
                $res = self::refund_order($order_id); //退款表数据写入
                if ($res) {
                    $or = Orders::query()->where('id', $order_id)->first();
                    if ($or) {
                        $refund_order->refund($or); //发起退款
                    } else {
                        return_bobc('订单不存在');
                    }
                } else {
                    return_bobc('订单不存在');
                }
            });
        } catch (\Exception $e) {
            return $e;
        };
        return 1;
    }

    /**
     * 退款订单
     */
    private function refund_order(int $order_id)
    {
        $type = 1;
        $order = Orders::query()->with('pay_order:id,sn,user_id,order_id,status')
            ->select(['id', 'is_pay_predict', 'predict_price', 'user_id', 'order_sn'])
            ->where('is_pay_predict', 1)
            ->where('id', $order_id)
            ->when($type, function ($query) use ($type) {
                return $query->whereHas('pay_order', function ($query) use ($type) {
                    return $query->where('status', '=', $type);
                });
            })
            ->first();
        if ($order) {
            $refun_order = new  RefundOrder;
            $refun_order->sn = uniqid();
            $refun_order->user_id = $order->user_id;
            $refun_order->order_id = $order->id;
            $refun_order->pay_order_id = $order->pay_order->id;
            $refun_order->pay_order_sn = $order->pay_order->sn;
            $refun_order->type = 3;
            $refun_order->price = $order->predict_price;
            $refun_order->refund_type = 1;
            $refun_order->time = time();
            $refun_order->status = 0;
            $refun_order->save();
            return true;
        } else {
            return false;
        }
    }

    public function driver_ids(int $order_id)
    {
        $rs = Orders::query()->where('id', $order_id)->first('driver_id');
        if ($rs) {
            return Drivers::query()->where('id', $rs->driver_id)->first('user_id');
        }
    }

    /**
     * @param $data
     * @return mixed
     */
    public function user_id($data)
    {
        $order = Orders::query()->where('id', $data['order_id'])->first('user_id');
        return $order->user_id;
    }


    /**
     * @param $data
     * @return int
     * 司机到达目的地
     */
    public function terminus($data)
    {
        $redis = new RedisOperation(); //实例化redis
        $order = new Orders();
        if (!$order->where('id', $data['order_id'])->where('status', '3')->first()) return 0;
        try {
            DB::transaction(function () use ($data, $redis, $order) {
                $orders = OrderDistance::query()->where([
                    ['order_id', $data['order_id']],
                ])
                    ->lockForUpdate()
                    ->first();
                if ($orders) {
                    $key = 'driver' . $data['order_id'];
                    $list = [];
                    $len = $redis->llen($key);
                    for ($i = 0; $i < $len; $i++) {
                        $list[] = $redis->rpop($key);
                    }
                    $orders->reality_end = $data['reality_end'];   //实际终点位置名称
                    $orders->reality_end_coord = $data['lng'] . ',' . $data['lat'];   //实际金纬度
                    $orders->reality_end_time = date('Y-m-d H:i:s'); //实际下车时间
                    $orders->tail_info = json_encode($list); //司机订单的轨迹信息
                    $orders->save();
                    $order->where('id', $data['order_id'])->update(['end_time' => date('Y-m-d H:i:s')]); //更改订单支付状态未支付的状态
                } else {
                    return_bobc('数据不存在');
                }
            });
        } catch (\Exception $e) {
            return 0;
        }
        return 1;
    }

    /**
     * 司机到达上车点
     */
    public function boardings($data)
    {
        $time = time(); //当前时间
        $status = '2';
        try {
            DB::transaction(function () use ($data, $time, $status) {
                $orders = OrderDistance::query()->with('orders:id,status')
                    ->where('order_id', $data['order_id'])
                    ->when($status, function ($query) use ($status) {
                        return $query->whereHas('orders', function ($query) use ($status) {
                            return $query->where('status', '=', $status);
                        });
                    })
                    ->first();
                if ($orders) {
                    $orders->reality_start = $data['reality_start'];    //实际起点密名称
                    $orders->reality_start_coord = $data['lng'] . ',' . $data['lat'];   //实际起点经纬度
                    $orders->save();
                    Orders::query()->where('id', $data['order_id'])->update(['arrive_time' => $time]); //写入司机到达时间
                } else {
                    return_bobc('该订单已被操作');
                }
            });
        } catch (\Exception $e) {
            return 0;
        }
        return $time;
    }

    /**
     * 确认接到乘客
     */
    public function to_passengerc(int $order_id)
    {
        $time = time();
        try {
            DB::transaction(function () use ($order_id, $time) {
                $orderss = Orders::query()->where([
                    ['id', $order_id],
                    ['status', '2'],
                ])->first();
                if ($orderss) {
                    $orderss->status = '3';    //订单状态：1预约中，2已接单，3正在服务，4未支付，5已支付，6已评价，-1乘客取消，-2司机取消，-3后台取消
                    $orderss->start_time = $time;  //开始时间
                    $orderss->save();
                    OrderDistance::query()->where('order_id', $order_id)->update(['reality_start_time' => date('Y-m-d H:i:s')]);
                }
            });
        } catch (\Illuminate\Database\QueryException $e) {
            return $e;
        }
        return 1;
    }

    /**
     * @param int $order_id
     * @return array|bool
     * 获取订单信息
     */
    public function order_info(int $order_id)
    {
        $info = Orders::query()->with('distance:id,order_id,book_start_coord')->select(['id', 'type'])->where([['id', $order_id], ['status', '1']])->first();
        if (!$info) return false;
        $lat = explode(',', $info->distance->book_start_coord);
        $arr = [];
        $arr['lat'] = $lat;   //预约经纬度
        $arr['type'] = $info->type; //订单类型
        return $arr;
    }

    /**
     * 获取订单状态
     */
    public function order_status($data)
    {
        $info = Orders::query()->where('id', $data['order_id'])->select(['id', 'status', 'arrive_time'])->first();
        return $info;
    }

    /**
     * @param $data
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|null|object
     *
     */
    public function order_statuss(int $driver_id)
    {
        $info = Orders::query()->where('driver_id', $driver_id)->whereIn('status', ['2', '3'])->first();
        return $info;
    }

    /**
     * 确认接单,网约车,代驾
     */
    public function ConfirmReceipt(int $order_id, int $drivers_id, int $car_id)
    {
        $orders = Orders::query()->where('id', $order_id)->where('status', '1')->first('type');
        if (!$orders) return 0;
        if ($orders->type == '0') return $this->drvingReceipts($order_id, $drivers_id, $car_id); //网约车
        if ($orders->type == '1') return $this->drvingReceipt($order_id, $drivers_id); //代驾
    }

    /**
     * 网约车接单
     */
    public function drvingReceipts(int $order_id, int $drivers_id, $car_id)
    {
        $car = Car::query()->where('id', $car_id)->select(['id', 'company_id', 'type'])->with('service:id,name')->first();
        try {
            DB::transaction(function () use ($order_id, $car, &$car_id, $drivers_id) {
                $orders = Orders::query()->where([
                    ['id', $order_id],
                    ['status', '1'],
                ])
                    ->lockForUpdate()
                    ->first();

                if ($orders) {
                    $orders->status = '2';        // 订单状态：1预约中，2已接单，3正在服务，4未支付，5已支付，6已评价，-1乘客取消，-2司机取消，-3后台取消
                    $orders->driver_id = $drivers_id; //接单司机ID
                    $orders->receive_time = time(); //接单时间错
                    $orders->car_id = $car_id;    //车辆ID
                    $orders->company_id = $car->company_id;   //司机所在公司
                    $orders->service_type_id = $car->type; //业务类型
                    $orders->service_id = $car->service->id; //服务类型
                    $orders->save();
                    self::user_info_company_id((int)$orders->user_id, (int)$car->company_id); //修改乘客公司ID
                } else {
                    return_bob('该订单已被操作');
                }
            });
        } catch (\Exception $e) {
            return 0;
        }
        return $car ? $car->type : 0;
    }

    /**
     * 代驾接单
     */
    public function drvingReceipt(int $order_id, int $drivers_id)
    {
        try {
            DB::transaction(function () use ($order_id, $drivers_id) {
                $orders = Orders::query()->where([
                    ['id', $order_id],
                    ['status', '1'],
                ])
                    ->lockForUpdate()
                    ->first();
                if ($orders) {
                    $drivers_others = DriverOthers::query()->where('driver_id', $drivers_id)->first('company_id');
                    $service = ServiceType::query()->where('id', $orders->call_service_type_id)->first('service_id');
                    $orders->status = '2';        // 订单状态：1预约中，2已接单，3正在服务，4未支付，5已支付，6已评价，-1乘客取消，-2司机取消，-3后台取消
                    $orders->driver_id = $drivers_id; //接单司机ID
                    $orders->receive_time = time(); //接单时间错
                    $orders->car_id = 0;    //车辆ID
                    $orders->company_id = $drivers_others->company_id;   //司机所在公司
                    $orders->service_type_id = $orders->call_service_type_id; //业务类型
                    $orders->service_id = $service->service_id; //服务类型\
                    $orders->save();
                    self::user_info_company_id((int)$orders->user_id, (int)$drivers_others->company_id); //修改乘客公司ID
                } else {
                    return_bob('该订单已被操作');
                }
            });
        } catch (\Exception $e) {
            return 0;
        }
        return 1;
    }

    /**
     * @param int $user_id
     * @param int $company_id
     * 修改乘客所在公司
     */
    public function user_info_company_id(int $user_id, int $company_id)
    {
        $res = User::query()->where('id', $user_id)->first();
        if ($res) {
            if ($res->company_id == 0 || $res->company_id == null || $res->company_id == 1) {
                $res->company_id = $company_id;
                $res->save();
            }
        }
    }

    /**
     * 接单状态时候的订单详情
     */
    public function order_details_show(int $order_id, User $user)
    {
        $driver_id = $user->driver()->first() ? $user->driver()->first()->id : 0;
        $list = Orders::query()
            ->leftJoin('service_type', 'service_type.id', 'orders.service_type_id')
            ->leftJoin('order_distance', 'order_distance.order_id', 'orders.id')
            ->leftJoin('users', 'users.id', 'orders.user_id')
            ->select('orders.id', 'order_distance.reality_start', 'order_distance.reality_end', 'order_distance.book_start_coord', 'order_distance.book_end_coord', 'orders.created_at', 'service_type.name', 'order_distance.reality_start', 'order_distance.reality_end', 'orders.status', 'users.phone', 'users.avatar', 'orders.type')
            ->where('orders.id', $order_id)
            ->where('orders.driver_id', $driver_id)
            ->whereIn('orders.status', ['2', '3'])
            ->first();
        if (!$list) return_bobc('订单不存在');
        $list = $list->toArray();
        $list['created_at'] = time_tran($list['created_at']);
        $list['last_phone'] = substr($list['phone'], -4); //截取手机后4位
        $map = new DriversPostage();
        if ($list['type'] == '1') {
            $rest = $map->drvingDriverOrderSettlement($list['id']); //预计费用计算
        } else {
            $rest = $map->DriversEstimatedCost($list['id']); //预计费用计算
        }
        $list['data'] = [
            'total_time' => $rest['total_time'], //预计时间
            'total_distance' => $rest['total_distance'], //总公里数
            'unpaid_cost' => number_format($rest['unpaid_cost'], 2, '.', ''), //预计费用保留两位小数
        ];
        return $list;
    }

    /**
     * @param int $order_id
     * @param $road_toll
     * @param $parking
     */
    public function ArriveAtTheBoardingPlacePy(int $order_id, $road_toll, $parking)
    {
        $type = $this->order_type($order_id); //获取订单类型
        if ($type == '0') return $this->ArriveAtTheBoardingPlace($order_id, $road_toll, $parking);
        if ($type == '1') return $this->drivingAtTheBoardingPlace($order_id, $road_toll, $parking);
    }

    /**
     *  司机确认到达乘车地点 发起收款 :网约车
     * @param int $order_id 订单ID
     * @param $road_toll 过路费
     * @param $parking 停车费
     * @return array
     */
    public function ArriveAtTheBoardingPlace(int $order_id, $road_toll, $parking)
    {
        $postage = new  DriversPostage();
        try {
            DB::transaction(function () use ($order_id, $road_toll, $parking, $postage) {
                $order = $postage->ActualCostOfPassengers($order_id); //乘客实际价钱
                $driver_momeny = $postage->DriverOrderSettlement($order_id); //司机所得费用
                $orders = Orders::query()->where([
                    ['id', $order_id],
                    ['status', '3'],
                ])
                    ->lockForUpdate()
                    ->first();
                if ($orders) {
                    $orders->toll_price = $road_toll;    //过路费
                    $orders->stop_price = $parking;   //停车费
                    $orders->status = '4';   //订单状态
                    $orders->minute = $order['minute'];   //总服务时间
                    $orders->km = $order['total_distance_km'];   //总里程
                    $orders->should_price = $order['unpaid_cost'] + $road_toll + $parking + $order['waiting_timeout']; //实收金额
                    $orders->driver_money = $driver_momeny['unpaid_cost'] + $road_toll + $parking + $driver_momeny['waiting_timeout'];   //司机应得费用
                    $orders->surplus_profit = $orders->should_price - $orders->driver_money; //剩余利润
                    $orders->waiting_time_price = $order['waiting_timeout']; //超时等待费用
                    $orders->cost_price = bcadd($order['unpaid_cost'], $order['waiting_timeout'], 2); //行程费
                    $orders->summary_time = time(); //结算时间戳
                    $orders->save();
                    $map = [
                        'details' => json_encode(self::details($order, $road_toll, $parking)),   //乘客资费详情数据
                        'driver_details' => json_encode(self::details($driver_momeny, $road_toll, $parking))   //司机资费详情数据
                    ];
                    OrderDistance::query()->where('order_id', $order_id)->update($map); //修改订单的资费信息数据
                    $this->DriverWallets($orders);//司机钱包
                    $this->driver_record_log($orders); //司机钱包明细
                } else {
                    return_bobc('该订单已被操作,请勿重复操作');
                }
            });

        } catch (\Illuminate\Database\QueryException $e) {

            return_bobc($e);
        }
        return ['order_id' => $order_id];
    }

    /**
     * @param object $driver_momeny
     * @param $road_toll
     * @param $parking
     * @return array
     */
    private function details(array $driver_momeny, $road_toll, $parking)
    {
        $mmp = [
            'basics_subsidy' => 0,
            'starting_price' => $driver_momeny['starting_price'], //起步价
            'waiting_timeout' => $driver_momeny['waiting_timeout'], //超时等候费
            'total_cost' => $driver_momeny['unpaid_cost'] + $road_toll + $parking + $driver_momeny['waiting_timeout'], //总费用
            'basics_cost' => round($driver_momeny['basics_cost'], 2), //基础费用
            'total_mileage_cost' => $driver_momeny['total_mileage_cost'], //总里程费用
            'total_duration_cost' => $driver_momeny['total_duration_cost'], //总时长费
            'total_long_distance_cost' => $driver_momeny['total_long_distance_cost'], //长途总费用
            'mileage' => self::mileage_duration_long_distance($driver_momeny['mileage']), //里程费详情
            'duration' => self::mileage_duration_long_distance($driver_momeny['duration']),  //时长费详情
            'long_distance' => self::mileage_duration_long_distance($driver_momeny['long_distance']), //长途费详情
        ];
        if ($driver_momeny['basics_cost'] >= $driver_momeny['unpaid_cost']) {
            $mmp['basics_subsidy'] = round($driver_momeny['basics_cost'] - $driver_momeny['total_mileage_cost'] - $driver_momeny['total_duration_cost'] - $driver_momeny['total_long_distance_cost'], 2); //基础费用
        }
        return $mmp;

    }

    /**
     * 代驾发起收款
     */
    public function drivingAtTheBoardingPlace($order_id, $road_toll, $parking)
    {
        $postage = new  DriversPostage();
        try {
            DB::transaction(function () use ($order_id, $road_toll, $parking, $postage) {
                $order = $postage->drivingActualCostOfPassengers($order_id); //乘客实际价钱
                $driver_momeny = $postage->drvingDriverOrderSettlement($order_id); //司机所得费用
                $orders = Orders::query()->where([
                    ['id', $order_id],
                    ['status', '3'],
                ])
                    ->lockForUpdate()
                    ->first();
                if ($orders) {
                    $orders->toll_price = $road_toll;    //过路费
                    $orders->stop_price = $parking;   //停车费
                    $orders->status = '4';   //订单状态
                    $orders->minute = $order['minute'];   //总服务时间
                    $orders->km = $order['total_distance_km'];   //总里程
                    $orders->should_price = $order['unpaid_cost'] + $road_toll + $parking + $order['waiting_timeout']; //实收金额
                    $orders->driver_money = $driver_momeny['unpaid_cost'] + $road_toll + $parking + $driver_momeny['waiting_timeout'];   //司机应得费用
                    $orders->surplus_profit = $orders->should_price - $orders->driver_money; //剩余利润
                    $orders->waiting_time_price = $order['waiting_timeout']; //超时等待费用
                    $orders->cost_price = bcadd($order['unpaid_cost'], $order['waiting_timeout'], 2); //行程费
                    $orders->summary_time = time(); //结算时间戳
                    $orders->save();
                    $map = [
                        'details' => json_encode(self::details_driving($order, $road_toll, $parking)),   //乘客资费详情数据
                        'driver_details' => json_encode(self::details_driving($driver_momeny, $road_toll, $parking))   //司机资费详情数据
                    ];
                    OrderDistance::query()->where('order_id', $order_id)->update($map); //修改订单的资费信息数据
                    //$passenger->createByOrderSuccess($orders); //发起收款
                    $this->DriverWallets($orders);//司机钱包
                    $this->driver_record_log($orders); //司机钱包明细
                } else {
                    return_bobc('该订单已被操作,请勿重复操作');
                }
            });

        } catch (\Illuminate\Database\QueryException $e) {

            return_bobc($e);
        }
        return ['order_id' => $order_id];
    }

    /**
     * @param array $driver_momeny
     * @param $road_toll
     * @param $parking
     * @return array
     */
    private function details_driving(array $driver_momeny, $road_toll, $parking)
    {
        $map = [
            'basics_subsidy' => 0, //基础费
            'waiting_timeout' => $driver_momeny['waiting_timeout'], //超时等候费
            'starting_price' => $driver_momeny['starting_price'], //起步价
            'total_cost' => $driver_momeny['unpaid_cost'] + $road_toll + $parking + $driver_momeny['waiting_timeout'], //总费用
            'basics_cost' => 0, //基础费用
            'total_mileage_cost' => 0, //总里程费用
            'total_duration_cost' => 0, //总时长费
            'total_long_distance_cost' => [], //长途总费用
            'mileage' => self::mileage_duration_long_distance($driver_momeny['mileage']), //里程费详情
            'duration' => [],  //时长费详情
            'long_distance' => [], //长途费详情
        ];
        return $map;
    }

    /**
     * @param array $data
     * @return array
     * 数据转换
     */
    private function mileage_duration_long_distance(array $data)
    {
        $list = null;
        foreach ($data as $key => $val) {
            $list = ['key' => $key, 'value' => $val];
        }
        return $list;
    }

    /**
     * 司机钱包管理
     */
    public function DriverWallets(object $orders)
    {

        $driver_wallets = DriverWallets::query()->where('driver_id', $orders->driver_id)->where('type', $orders->type)->first();

        if (!$driver_wallets) {
            $map = [
                'driver_id' => $orders->driver_id, //司机ID
                'settled_amount' => $orders->driver_money, //司机应得
                'balance' => $orders->driver_money, //司机余额
                'amount' => 0,  //可提现金额
                'type' => $orders->type, //钱包类型
                'created_at' => Carbon::now(),
                'updated_at' => Carbon::now()
            ];
            DriverWallets::query()->insert($map);
        } else {
            DriverWallets::query()->where('driver_id', $orders->driver_id)->where('type', $orders->type)->update([
                'settled_amount' => DB::raw('settled_amount + ' . $orders->driver_money),
                'balance' => DB::raw('balance + ' . $orders->driver_money),
            ]);
        }

    }

    /**
     * @param object $orders
     * 新增钱包日志日志
     */
    public function driver_record_log(object $orders)
    {
        $driver_record_log = new  DriverRecordLog();
        $driver_record_log->driver_id = $orders->driver_id;
        $driver_record_log->name = '订单结算';
        $driver_record_log->money = $orders->driver_money;
        $driver_record_log->stard_time = date('Y-m-d H:i:s');
        $driver_record_log->order_sn = $orders->order_sn;
        $driver_record_log->set_type = '2';
        $driver_record_log->status = '1';
        $driver_record_log->in_type = '1';
        $driver_record_log->note = '订单结算';
        $driver_record_log->rules = $orders->type; //类型
        $driver_record_log->save();
    }

    /**
     * 乘客 司机接单数据
     */
    public function driver_info($data)
    {
        $postage = new  DriversPostage();
        $datas = [];
        $info = Orders::query()->with('order_distance:id,order_id,book_start_coord,book_end_coord,reality_start')
            ->select(['id', 'user_id', 'status', 'driver_id', 'arrive_time', 'end_time'])
            ->where('id', $data['order_id'])
            ->first();
        $lat_lng = $info->order_distance->book_start_coord; //默认司机位置就是乘客起点位置
        if ($info) {
            if ($this->redis->exists('driver' . $info->driver_id)) {
                $ss = $this->redis->get('driver' . $info->driver_id);
                if (!empty($ss)) {
                    $ss = explode(',', $ss);
                    $lat_lng = $ss[1] . ',' . $ss[0];
                }
            }

            if ($info->order_distance->reality_start != '' || $info->order_distance->reality_start != null) {
                $coord = $info->order_distance->book_end_coord;
                // $datas = $postage->DriversEstimatedCostssss($lat_lng, $info->order_distance->book_end_coord); //预计时间与预计公里数
            } else {
                $coord = $info->order_distance->book_start_coord;
                //$datas = $postage->DriversEstimatedCostssss($lat_lng, $info->order_distance->book_start_coord); //预计时间与预计公里数
            }
            $datas = $postage->DriversEstimatedCostssss($lat_lng, $coord); //预计时间与预计公里数
            $datas['status'] = $info->status;
            $datas['arrive_time'] = $info->arrive_time;
            $datas['driver_latitude'] = $lat_lng; //司机经纬度
            $datas['user_id'] = $info->user_id; //乘客ID
            $datas['reality_start'] = $info->order_distance->reality_start; //乘客ID
            $datas['end_time'] = $info->end_time; //乘客ID
        }

        return $datas;
    }

    /**
     * 选单接口
     * @param $lat
     * @param $lng
     * @param User $user
     */
    public function driverMenu(User $user, string $lng, string $lat, int $car_id, string $type)
    {
        if ($type == '0') {
            $company_id = $user->driver()->first()->company_id; //城市ID
            if (!$company_id) return_bobc('公司不存在');
            $types = Car::query()->where('id', $car_id)->first('type');
            $type_id = $types->type;
        } else {
            $driver_id = $user->driver()->first()->id; //司机ID
            $driver_dving = DriverOthers::query()->where('driver_id', $driver_id)->first();
            $company_id = $driver_dving ? $driver_dving->company_id : $user->driver()->first()->company_id;
            $type_id = '';
        }
        $city = \App\Models\ServiceCity::query()->where('default_driver_company_id', $company_id)->first('city_id');
        $city_id = $city ? $city->city_id : '';
        return self::order_get_list($type, $city_id, $type_id, $lng, $lat);
    }

    /**
     * @param $type
     * @param $city_id
     * @param $type_id
     * @param $lng
     * @param $lat
     * @return object
     */
    private function order_get_list($type, $city_id, $type_id, $lng, $lat)
    {
        $list = Orders::query()
            ->where('status', '1')
            ->where('type', $type)
            ->where('city_id', $city_id)
            ->where('call_service_type_id', 'like', '%' . $type_id . '%')
            //  ->whereTime('created_at', '<', date('Y-m-d H:i:s', time() - 60))
            ->select(['id', 'created_at', 'call_service_type_id', 'type', 'types'])
            ->orderByDesc('created_at')
            ->get();
        return self::driverMenus($list, $type_id, $lng, $lat);
    }

    /**
     * @param object $list
     * @param $type_id
     * @param string $lng
     * @param string $lat
     * @return object
     */
    protected function driverMenus(object $list, $type_id, string $lng, string $lat)
    {

        $ss = new DriversPostage();
        foreach ($list as $key => $value) {
            if ($value['type'] == '0') {
                $info = $ss->DriversEstimatedCosts($value['id'], $type_id);
            } else {
                $info = $ss->EstimatedCost($value['id']);
            }
            $book_start_coord = explode(',', $info['book_start_coord']);
            $list[$key]['info'] = $info;
            $list[$key]['distance'] = self::getDistance($lng, $lat, $book_start_coord[0], $book_start_coord[1], 2); //距离当前司机的位置计算
        }
        return $list;
    }

    /**
     * 距离计算
     * @param $longitude1
     * @param $latitude1
     * @param $longitude2
     * @param $latitude2
     * @param int $unit
     * @param int $decimal
     * @return float
     */
    private function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit = 2, $decimal = 2)
    {

        $EARTH_RADIUS = 6370.996; // 地球半径系数

        $PI = 3.1415926;

        $radLat1 = $latitude1 * $PI / 180.0;
        $radLat2 = $latitude2 * $PI / 180.0;

        $radLng1 = $longitude1 * $PI / 180.0;
        $radLng2 = $longitude2 * $PI / 180.0;

        $a = $radLat1 - $radLat2;
        $b = $radLng1 - $radLng2;

        $distance = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
        $distance = $distance * $EARTH_RADIUS * 1000;

        if ($unit == 2) {
            $distance = $distance / 1000;
        }
        return round($distance, $decimal);
    }

    /**
     * 司机确认账单页面数据
     */
    public function DriverConfirmsBill(int $order_id)
    {
        $postage = new  DriversPostage();
        $order = $postage->DriverOrderSettlement($order_id);
        $order['order_id'] = $order_id;
        return $order;
    }

    /**
     * 代驾司机确认账单页面数据
     */
    public function drivingDriverConfirmsBill(int $order_id)
    {
        $postage = new  DriversPostage();
        $order = $postage->drvingDriverOrderSettlement($order_id);
        $order['order_id'] = $order_id;
        return $order;
    }

    /**
     * 乘客订单状态监测
     */
    public function passenger_status(int $order_id)
    {
        return Orders::query()->where('id', $order_id)->whereIn('status', ['2', '3'])->select(['id', 'driver_id', 'user_id'])->first();
    }

    /**
     * 查询所有订单暂时没有考虑城市
     */
    public function order_list_push()
    {
        return Orders::query()->where('status', '1')->select(['id', 'user_id', 'company_id', 'driver_id'])->get();
    }

    /**
     * 司机业务类型查询
     */
    public function driver_type(int $driver_id)
    {
        if ($this->redis->exists('car' . $driver_id)) $car_id = $this->redis->get('car' . $driver_id);
        $type = Car::query()->where('id', $car_id)->first('type');
        return $type ? $type->type : '0';
    }

    /**
     * 通过user_id 获取司机ID
     */
    public function drivers_in_id(int $user_id)
    {
        //return User::query()->with('driver:id,user_id')->where('id', $user_id)->select(['id'])->first();
        return Drivers::query()->where('user_id', $user_id)->first('id');
    }

    /**
     * 通过司机ID 获取用户ID
     */
    public function drivers_user_id(int $driver_id)
    {
        return Drivers::query()->where('id', $driver_id)->first('user_id');
    }

    /**获取订单类型
     *
     */
    public function order_type(int $order_id)
    {
        $order = Orders::query()->where('id', $order_id)->first('type');
        return $order->type;
    }
}